from typing import List, Any

from PyQt5.QtWidgets import QWidget, QGraphicsView, QGraphicsScene, QGraphicsItem
from PyQt5.QtCore import QPoint, QPointF, QRectF, QRect, Qt
from PyQt5.QtGui import QTransform, QPixmap

from Tools.Transform.Controller.Controller import Controller, ControllerTag
from Tools.Transform.Controller.TransformEvent import TransformEvent
import GUI.Window.Editor as WindowEditor


class ScalerTag(ControllerTag):
    isCorner = False
    opposite = None


class Scaler(Controller):
    PreviousTransform = None

    def __init__(self, parent: QWidget, layer) -> QWidget:
        """
        :param parent:  QWidget
        :param layer:
        :return QWidget #handle of the indicator
        """
        super().__init__(parent, layer)
        self.Name = 'Scaler'
        self.PreviousTransform = self.graphicsItem.transform()
        self.initTag()
        self.updateTagPos()

    def setEditorWidget(self, editorWidget):
        # 编辑组件
        self.editorWidget = editorWidget
        self.editorWidget.confirmAction = self.confirm
        self.editorWidget.cancelAction = self.cancel

    @property
    def __newTag(self):
        return ScalerTag(self.Parent, self)

    def initTag(self):
        # 新建tag
        # 0 1 2
        # 3   4
        # 5 6 7
        for i in range(0, 8):
            self.TagList.append(self.__newTag)
            self.TagList[i].Index = i
        # 定义角落
        for i in (0, 2, 5, 7):
            self.TagList[i].isCorner = True
        # 相对的Tag
        length = len(self.TagList)
        for i in range(0, 4):
            self.TagList[i].opposite = self.TagList[length - 1 - i]
            self.TagList[length - 1 - i].opposite = self.TagList[i]
        # 设置鼠标
        self.TagList[0].setCursor(Qt.SizeFDiagCursor)
        self.TagList[7].setCursor(Qt.SizeFDiagCursor)
        self.TagList[1].setCursor(Qt.SizeVerCursor)
        self.TagList[6].setCursor(Qt.SizeVerCursor)
        self.TagList[2].setCursor(Qt.SizeBDiagCursor)
        self.TagList[5].setCursor(Qt.SizeBDiagCursor)
        self.TagList[3].setCursor(Qt.SizeHorCursor)
        self.TagList[4].setCursor(Qt.SizeHorCursor)

    def updateTagPos(self):
        tagList = self.TagList
        graphicsItem = self.graphicsItem
        scene: QGraphicsScene = graphicsItem.scene()
        view: QGraphicsView = scene.views()[0]
        if view:
            rect: QRectF = graphicsItem.sceneBoundingRect()
            topLeft = view.mapFromScene(rect.topLeft())
            bottomRight = view.mapFromScene(rect.bottomRight())
            # 视图坐标 → 全局 → ImagePanel坐标
            topLeft: QPoint = self.Parent.mapFromGlobal(view.mapToGlobal(topLeft))
            bottomRight: QPoint = self.Parent.mapFromGlobal(view.mapToGlobal(bottomRight))
            rect = QRect(topLeft, bottomRight)
            # print('topLeft:',topLeft.xRate(), topLeft.yRate())
            # print('bottomRight:', bottomRight.xRate(), bottomRight.yRate())
            for i in range(0, len(tagList)):
                anchor = self._getRectAnchor(rect, i)
                tagList[i].move2(anchor.x(), anchor.y())

    @staticmethod
    def _getRectAnchor(rect: QRectF, anchorIndex):
        """
        0 1 2
        3   4
        5 6 7
        :param rect: QRectF | QRect
        :param anchorIndex:
        :return:
        """
        if anchorIndex == 0:
            anchor = rect.topLeft()
        elif anchorIndex == 1:
            anchor = QPointF((rect.topLeft().x() + rect.topRight().x()) / 2, rect.topLeft().y())
        elif anchorIndex == 2:
            anchor = rect.topRight()
        elif anchorIndex == 3:
            anchor = QPointF(rect.topLeft().x(), (rect.topLeft().y() + rect.bottomLeft().y()) / 2)
        elif anchorIndex == 4:
            anchor = QPointF(rect.topRight().x(), (rect.topRight().y() + rect.bottomRight().y()) / 2)
        elif anchorIndex == 5:
            anchor = rect.bottomLeft()
        elif anchorIndex == 6:
            anchor = QPointF((rect.bottomLeft().x() + rect.bottomRight().x()) / 2, rect.bottomLeft().y())
        elif anchorIndex == 7:
            anchor = rect.bottomRight()
        else:
            anchor = rect.center()
        return anchor

    def onTransformEvent(self, event: TransformEvent):
        """
        缩放器操作
        :param event: TransformEvent
        :return:
        """
        # print('onTransform')
        tag: ScalerTag = self.OperatingTag
        if tag is None:
            return
        graphicsItem = self.graphicsItem
        scene: QGraphicsScene = graphicsItem.scene()
        view: QGraphicsView = scene.views()[0]
        if view:
            # previous = event.PreviousMousePos
            # current = event.CurrentMousePos
            previous = view.mapToScene(view.mapFromGlobal(self.Parent.mapToGlobal(event.PreviousMousePos)))
            current = view.mapToScene(view.mapFromGlobal(self.Parent.mapToGlobal(event.CurrentMousePos)))
            itemRect: QRectF = graphicsItem.sceneBoundingRect()
            # topLeft = view.mapFromScene(rect.topLeft())
            # bottomRight = view.mapFromScene(rect.bottomRight())
            # pos = view.mapFromScene()
            width, height = itemRect.width(), itemRect.height()
            x1, y1, x2, y2 = previous.x(), previous.y(), current.x(), current.y()
            # 变换中心点
            oppositeTagIndex = tag.opposite.Index
            anchor: QRectF = graphicsItem.mapFromScene(self._getRectAnchor(itemRect, oppositeTagIndex))

            if tag.isCorner:
                xRate, yRate = (abs(x2-x1)) / width, (abs(y2-y1)) / height
                if abs(x2-anchor.x()) > abs(x1-anchor.x()):
                    xRate = xRate + 1
                else:
                    xRate = 1 - xRate
                    if xRate < 0.1:
                        xRate = 0.1
                if abs(y2-anchor.y()) > abs(y1-anchor.y()):
                    yRate = yRate + 1
                else:
                    yRate = 1 - yRate
                    if yRate < 0.1:
                        yRate = 0.1
            else:
                tagIndex = tag.Index
                if tagIndex == 1 or tagIndex == 6:
                    xRate, yRate = 1, abs(y2 - y1) / height
                    if abs(y2 - anchor.y()) > abs(y1 - anchor.y()):
                        yRate = yRate + 1
                    else:
                        yRate = 1 - yRate
                        if yRate < 0.1:
                            yRate = 0.1
                else:
                    xRate, yRate = abs(x2 - x1) / width, 1
                    if abs(x2 - anchor.x()) > abs(x1 - anchor.x()):
                        xRate = xRate + 1
                    else:
                        xRate = 1 - xRate
                        if xRate < 0.1:
                            xRate = 0.1
            # 变换
            transform = QTransform()
            transform.translate(anchor.x(), anchor.y())
            transform.scale(xRate, yRate)
            graphicsItem.setTransform(transform, True)
            transform.reset()
            transform.translate(- anchor.x(), - anchor.y())
            graphicsItem.setTransform(transform, True)
            self.updateTagPos()
            # if tag.isCorner:

    def destroy(self):
        for each in self.TagList:
            each.deleteLater()
        self.TagList.clear()
        # 删除控制器编辑面板
        WindowEditor.delEditor(self.editorWidget)
        # 移除控制器
        self.Parent.removeController(self)
        Controller.destroy(self)
        print('缩放器删除')

    def confirm(self):
        print('缩放器确认')
        self.destroy()
        # 保存图层
        self.layer.updateImage()

    def cancel(self):
        print('缩放器取消')
        self.graphicsItem.setTransform(self.PreviousTransform)
        self.destroy()
